﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using MySql.Data.MySqlClient;
using BartonExtension;
using Services.Common;
using SQLWrapper;
using Model.App;
using Model.Images;

namespace Services.Activity
{
    public class ISMActivityServiceProvider : ISMServiceProvider
    {
        public const string GET_ACTS = "get_acts";
        public const string GET_SINGLE_ACT = "get_single_act";
        public const string ADD_ACTS = "add_act";
        public const string CANCEL_ACTS = "cancel_acts";
        public const string GET_ACT_REQUIRED_FORM = "get_act_required_form";
        public const string GET_SUBS = "get_subs";
        public const string SUB_ACT = "sub_act";
        public override Task<ISMServiceResult> doProcess(ISMServiceModel model)
        {
            if(model.operationIdentifier == GET_ACTS)
            {
                ISMGetActivitiesRequest request = model.GetState<ISMGetActivitiesRequest>();
                return GetActivities(request);
            }
            else if(model.operationIdentifier == GET_SINGLE_ACT)
            {
                ISMGetSingleActivitieRequest request = model.GetState<ISMGetSingleActivitieRequest>();
                return GetSingleActivitie(request);
            }
            else if(model.operationIdentifier == ADD_ACTS)
            {
                ISMAddActivityRequest request = model.GetState<ISMAddActivityRequest>();
                return AddActivity(request);
            }
            else if(model.operationIdentifier == CANCEL_ACTS)
            {
                ISMActivitieOperationRequest request = model.GetState<ISMActivitieOperationRequest>();
                return CancelActivity(request);
            }
            else if(model.operationIdentifier == GET_SUBS)
            {
                ISMGetActivitieSubsRequest request = model.GetState<ISMGetActivitieSubsRequest>();
                return GetActivitieSubs(request);
            }
            else if(model.operationIdentifier == SUB_ACT)
            {
                ISMActivitieOperationRequest request = model.GetState<ISMActivitieOperationRequest>();
                return SubActivitie(request);
            }
            else if(model.operationIdentifier == GET_ACT_REQUIRED_FORM)
            {
                ISMActivitieOperationRequest request = model.GetState<ISMActivitieOperationRequest>();
                return GetActivitieRequiredForm(request);
            }
            else
            {
                return base.defaultProcess();
            }
        }
        private Task<ISMServiceResult> GetActivities(ISMGetActivitiesRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    MySQLOperationManager.doSQLOperationWithLoadedData(cmd =>
                    {
                        cmd.CommandText = "proc_client_get_activities";
                        cmd.Parameters.Add("?_parameterState", request.parameterState, ParameterDirection.Input);
                        cmd.Parameters.Add("?startIdx", request.page * request.pageSize, ParameterDirection.Input);
                        cmd.Parameters.Add("?endIdx", (request.page + 1) * request.pageSize, ParameterDirection.Input);
                        cmd.Parameters.Add("?_contentType", request.type, ParameterDirection.Input);
                        cmd.Parameters.Add("?_myid", request.uid, ParameterDirection.Input);
                        cmd.Parameters.Add("?_token", request.token, ParameterDirection.Input);
                    },
                    e =>
                    {
                        if (e != null)
                        {
                            result.isOperationSuccess = false;
                            result.errorMsg = e;
                            result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                        }
                    },
                    data =>
                    {
                        if (data.Count == 1 && data.First().ContainsKey("error"))
                        {
                            result.isOperationSuccess = false;
                            result.errorMsg = "Token 验证失败";
                            result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                        }
                        else
                        {
                            List<ISMActivity> activities = new List<ISMActivity>();
                            data.ForEach(d =>
                            {
                                ISMActivity act = new ISMActivity();
                                act.ID = d["ID"].toUInt64().Value;
                                act.subflag = d["subflag"].toBoolean().Value;
                                act.act_title = d["act_title"].ToString();
                                act.act_content = d["act_content"].ToString();
                                act.act_location = d["act_location"].ToString();
                                act.act_time = d["act_time"].ToString().Replace("T", " ");
                                act.act_fee = d["act_fee"].toFloat().Value;
                                act.act_limitation = d["act_limitation"].toUInt32().Value;
                                act.act_sub_deadline = d["act_sub_deadline"].ToString().Replace("T", " ");
                                act.act_subs = d["act_subs"].toUInt32().Value;
                                act.act_status = d["act_status"].toEnum<PublishStatus>();
                                act.timetag = d["timetag"].ToString();
                                act.publisher = new ISMUserinfo()
                                {
                                    ID = d["ID"].ToString().toInt64().Value,
                                    openId = d["openid"].ToString(),
                                    intopenid = d["intopenid"].ToString(),
                                    wechatName = d["wechatname"].ToString(),
                                    username = d["username"].ToString(),
                                    sex = (Sex)d["sex"].ToString().toInt32().Value,
                                    vocation = d["vocation"].ToString(),
                                    company = d["company"].ToString(),
                                    occupation = d["occupation"].ToString(),
                                    mobile = d["mobile"].ToString(),
                                    telephone = d["telephone"].ToString(),
                                    email = d["email"].ToString(),
                                    officeAddress = d["officeaddress"].ToString(),
                                    piccardUrl = d["piccardUrl"].ToString(),
                                    videocardUrl = d["piccardUrl"].ToString(),
                                    headimgUrl = d["headimgUrl"].ToString()
                                };
                                string imgs = d["img_urls"].ToString();
                                if (imgs != "#na")
                                {
                                    int i = 0;
                                    imgs.Split('&').ToList().ForEach(img =>
                                    {
                                        try
                                        {
                                            Model.Images.UploadImageEntity entity = new Model.Images.UploadImageEntity()
                                            {
                                                imageID = d["img_ids"].ToString().Split('&')[i].toInt64().Value,
                                                ori_image_url = img
                                            };
                                            entity.generateThumbs();
                                            act.images.Add(entity);
                                        }
                                        catch (Exception e) { }
                                        i++;
                                    });
                                }
                                activities.Add(act);
                            });
                            result.dbReturningState = activities;
                        }
                    }, CommandType.StoredProcedure, false);
                    return result;
                });
        }
        private Task<ISMServiceResult> GetSingleActivitie(ISMGetSingleActivitieRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    MySQLOperationManager.doSQLOperationWithLoadedData(
                        cmd =>
                        {
                            cmd.CommandText = "proc_client_get_single_activitie";
                            cmd.Parameters.Add("?_uid", request.uid, ParameterDirection.Input);
                            cmd.Parameters.Add("?_act_id", request.act_id, ParameterDirection.Input);
                            cmd.Parameters.Add("?_token", request.token, ParameterDirection.Input);
                        },
                        e =>
                        {
                            if (e != null)
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                                result.errorMsg = e;
                            }
                        },
                        data =>
                        {
                            if (data.Count == 1 && data.First().ContainsKey("error"))
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                                result.errorMsg = "Token 验证失败";
                            }
                            else if (data.Count == 1 && data.First().ContainsKey("act_not_exist"))
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_UNKNOWN_ERR;
                                result.errorMsg = "该活动不存在";
                            }
                            else if (data.Count == 0)
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_AUTHORIZERIGHTSFAIL;
                                result.errorMsg = "无权查看该活动";
                            }
                            else
                            {
                                var d = data.First();
                                ISMActivity act = new ISMActivity();
                                act.ID = d["ID"].toUInt64().Value;
                                act.subflag = d["subflag"].toBoolean().Value;
                                act.act_title = d["act_title"].ToString();
                                act.act_content = d["act_content"].ToString();
                                act.act_location = d["act_location"].ToString();
                                act.act_time = d["act_time"].ToString().Replace("T", " ");
                                act.act_fee = d["act_fee"].toFloat().Value;
                                act.act_limitation = d["act_limitation"].toUInt32().Value;
                                act.act_sub_deadline = d["act_sub_deadline"].ToString().Replace("T", " ");
                                act.act_subs = d["act_subs"].toUInt32().Value;
                                act.act_status = d["act_status"].toEnum<PublishStatus>();
                                act.timetag = d["timetag"].ToString();
                                act.publisher = new ISMUserinfo()
                                {
                                    ID = d["ID"].ToString().toInt64().Value,
                                    openId = d["openid"].ToString(),
                                    intopenid = d["intopenid"].ToString(),
                                    wechatName = d["wechatname"].ToString(),
                                    username = d["username"].ToString(),
                                    sex = (Sex)d["sex"].ToString().toInt32().Value,
                                    vocation = d["vocation"].ToString(),
                                    company = d["company"].ToString(),
                                    occupation = d["occupation"].ToString(),
                                    mobile = d["mobile"].ToString(),
                                    telephone = d["telephone"].ToString(),
                                    email = d["email"].ToString(),
                                    officeAddress = d["officeaddress"].ToString(),
                                    piccardUrl = d["piccardUrl"].ToString(),
                                    videocardUrl = d["piccardUrl"].ToString(),
                                    headimgUrl = d["headimgUrl"].ToString()
                                };
                                string imgs = d["img_urls"].ToString();
                                if (imgs != "#na")
                                {
                                    int i = 0;
                                    imgs.Split('&').ToList().ForEach(img =>
                                    {
                                        try
                                        {
                                            Model.Images.UploadImageEntity entity = new Model.Images.UploadImageEntity()
                                            {
                                                imageID = d["img_ids"].ToString().Split('&')[i].toInt64().Value,
                                                ori_image_url = img
                                            };
                                            entity.generateThumbs();
                                            act.images.Add(entity);
                                        }
                                        catch (Exception e) { }
                                        i++;
                                    });
                                }
                                result.dbReturningState = act;
                            }
                        }, CommandType.StoredProcedure, false);
                    return result;
                });
        }
        private Task<ISMServiceResult> AddActivity(ISMAddActivityRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    MySQLOperationManager.doSQLOperation(cmd =>
                        {
                            cmd.CommandText = "proc_client_add_activitie";
                            cmd.Parameters.Add("?_aid", request.ID, ParameterDirection.Input);
                            cmd.Parameters.Add("?_act_title", request.act_title, ParameterDirection.Input);
                            cmd.Parameters.Add("?_act_content", request.act_content, ParameterDirection.Input);
                            cmd.Parameters.Add("?_act_location", request.act_location, ParameterDirection.Input);
                            cmd.Parameters.Add("?_act_time", request.act_time, ParameterDirection.Input);
                            cmd.Parameters.Add("?_act_fee", request.act_fee, ParameterDirection.Input);
                            cmd.Parameters.Add("?_act_limitation", request.act_limitation, ParameterDirection.Input);
                            cmd.Parameters.Add("?_act_sub_deadline", request.act_sub_deadline, ParameterDirection.Input);
                            cmd.Parameters.Add("?_act_publisher", request.publisherId, ParameterDirection.Input);
                            cmd.Parameters.Add("?_act_view_permission", request.act_view_permission, ParameterDirection.Input);
                            cmd.Parameters.Add("?_form_identifier", request.form_identifier, ParameterDirection.Input);
                            cmd.Parameters.Add("?_tags", request.parameterState == null ? "" : request.parameterState, ParameterDirection.Input);
                            cmd.Parameters.Add("?_image_ids", request.image_ids == null ? "" : request.image_ids, ParameterDirection.Input);
                            cmd.Parameters.Add("?_token", request.token, ParameterDirection.Input);
                            cmd.Parameters.Add("?errorcode", MySqlDbType.Int32, ParameterDirection.Output);
                            cmd.ExecuteNonQuery();
                            int errorcode = cmd.Parameters["?errorcode"].Value.toInt32().Value;
                            if(errorcode == -1)
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                                result.errorMsg = "Token 验证失败";
                            }
                            else if(errorcode == -2)
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_UNKNOWN_ERR;
                                result.errorMsg = "未知错误";
                            }
                        },
                        e =>
                        {
                            if(e != null)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = e;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                            }
                        }, CommandType.StoredProcedure, false);
                    return result;
                });
        }
        private Task<ISMServiceResult> CancelActivity(ISMActivitieOperationRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    MySQLOperationManager.doSQLOperation(cmd =>
                        {
                            cmd.CommandText = "proc_client_set_activitie_status";
                            cmd.Parameters.Add("?_aid", request.aid,ParameterDirection.Input);
                            cmd.Parameters.Add("?_act_status", request.state.FromJson<Dictionary<string, object>>()["status"], ParameterDirection.Input);
                            cmd.Parameters.Add("?_uid", request.state.FromJson<Dictionary<string, object>>()["uid"], ParameterDirection.Input);
                            cmd.Parameters.Add("?_token", request.token,ParameterDirection.Input);
                            cmd.Parameters.Add("?errorcode", MySqlDbType.Int32, ParameterDirection.Output);
                            cmd.ExecuteNonQuery();
                            int errorcode = cmd.Parameters["?errorcode"].Value.toInt32().Value;
                            if(errorcode == -1)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = "Token 验证失败";
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                            }
                            else if(errorcode == -2)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = "权限不足";
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_AUTHORIZERIGHTSFAIL;
                            }
                        },
                        e =>
                        {
                            if(e != null)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = e;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                            }
                        }, CommandType.StoredProcedure, false);
                    return result;
                });
        }
        private Task<ISMServiceResult> GetActivitieSubs(ISMGetActivitieSubsRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    MySQLOperationManager.doSQLOperationWithLoadedData(cmd =>
                        {
                            cmd.CommandText = "proc_client_get_activitie_subs";
                            cmd.Parameters.Add("?_aid", request.aid, ParameterDirection.Input);
                            cmd.Parameters.Add("?startIdx", request.page * request.pageSize, ParameterDirection.Input);
                            cmd.Parameters.Add("?endIdx", (request.page+1) * request.pageSize, ParameterDirection.Input);
                            cmd.Parameters.Add("?_token", request.token, ParameterDirection.Input);
                        },
                        e =>
                        {
                            if(e != null)
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                                result.errorMsg = e;
                            }
                        },
                        data =>
                        {
                            if(data.Count == 1 && data.First().ContainsKey("error"))
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                                result.errorMsg = "Token 验证失败";
                            }
                            else
                            {
                                List<ISMActivitieSubscriber> subscribers = new List<ISMActivitieSubscriber>();
                                data.ForEach(d =>
                                    {
                                        ISMActivitieSubscriber subscriber = new ISMActivitieSubscriber()
                                        {
                                            aid = request.aid,
                                            userinfo = new ISMUserinfo()
                                            {
                                                ID = d["uid"].ToString().toInt64().Value,
                                                openId = d["openid"].ToString(),
                                                intopenid = d["intopenid"].ToString(),
                                                wechatName = d["wechatname"].ToString(),
                                                username = d["username"].ToString(),
                                                sex = (Sex)d["sex"].ToString().toInt32().Value,
                                                vocation = d["vocation"].ToString(),
                                                company = d["company"].ToString(),
                                                occupation = d["occupation"].ToString(),
                                                mobile = d["mobile"].ToString(),
                                                telephone = d["telephone"].ToString(),
                                                email = d["email"].ToString(),
                                                officeAddress = d["officeaddress"].ToString(),
                                                piccardUrl = d["piccardUrl"].ToString(),
                                                videocardUrl = d["piccardUrl"].ToString(),
                                                headimgUrl = d["headimgUrl"].ToString()
                                            },
                                            timetag = d["timetag"].ToString()
                                        };
                                        subscribers.Add(subscriber);
                                    });
                                result.dbReturningState = subscribers;
                            }
                        }, CommandType.StoredProcedure, false);
                    return result;
                });
        }
        private Task<ISMServiceResult> GetActivitieRequiredForm(ISMActivitieOperationRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    MySQLOperationManager.doSQLOperationWithLoadedData(cmd =>
                        {
                            cmd.CommandText = "proc_client_get_activitie_required_form";
                            cmd.Parameters.Add("?_aid", request.aid, ParameterDirection.Input);
                            cmd.Parameters.Add("?_token", request.token, ParameterDirection.Input);
                        },
                        e =>
                        {
                            if(e != null)
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                                result.errorMsg = e;
                            }
                        },
                        data =>
                        {
                            if (data.Count == 1 && data.First().ContainsKey("error"))
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = "Token 验证失败";
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                            }
                            else if (data.Count == 1 && data.First().ContainsKey("act_canceled"))
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = "活动已取消";
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ACTIVITY_CANCELED;
                            }
                            else
                            {
                                ISMForm form = ISMForm.NewForm();
                                data.ForEach(d =>
                                    {
                                        ISMFormField field = new ISMFormField()
                                        {
                                            ID = d["ID"].toUInt64().Value,
                                            field_desc = d["field_desc"].ToString(),
                                            field_name = d["field_name"].ToString(),
                                            field_type = d["field_type"].toEnum<ISMFormFieldType>()
                                        };
                                        form.fields.Add(field);
                                    });
                                result.dbReturningState = form;
                            }
                        }, CommandType.StoredProcedure, false);
                    return result;
                });
        }
        private Task<ISMServiceResult> SubActivitie(ISMActivitieOperationRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    MySQLOperationManager.doSQLOperation(cmd =>
                        {
                            cmd.CommandText = "proc_client_sub_act";
                            cmd.Parameters.Add("?_aid", request.aid, ParameterDirection.Input);
                            cmd.Parameters.Add("?_uid", request.state.FromJson<Dictionary<string,object>>()["uid"], ParameterDirection.Input);
                            cmd.Parameters.Add("?_filled_form_id", request.state.FromJson<Dictionary<string, object>>()["filled_form_id"], ParameterDirection.Input);
                            cmd.Parameters.Add("?_token", request.token, ParameterDirection.Input);
                            cmd.Parameters.Add("?errorcode", MySqlDbType.Int32, ParameterDirection.Output);
                            cmd.ExecuteNonQuery();
                            int errorcode = cmd.Parameters["?errorcode"].Value.toInt32().Value;
                            if(errorcode == -1)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = "Token 验证失败";
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                            }
                            else if (errorcode == -2)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = "您已报名";
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ACTIVITY_ALREADY_SUBSCRIBED;
                            }
                            else if (errorcode == -3)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = "该活动已取消";
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ACTIVITY_CANCELED;
                            }
                            else if (errorcode == -4)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = "该活动报名人数已满";
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ACTIVITY_SUB_FULL;
                            }
                        },
                        e =>
                        {
                            if(e != null)
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                                result.errorMsg = e;
                            }
                        }, CommandType.StoredProcedure, false);
                    return result;
                });
        }
    }
}
